using System;
using System.Collections.Generic;
using System.IO;
using SCore.Editor.BuildPackage.Platform;
using Function.SerializedPropertyAttribute;
using SCore.Util;
using UnityEditor;
using UnityEditor.Android;
using UnityEngine;

namespace SCore.Editor.BuildPackage
{
    [CustomEditor(typeof(BuildChannel))]
    public class BuildChannelEditor : ObjectDrawEditor<BuildChannel>
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            BuildChannel sBuildChannel = target as BuildChannel;
            var platformName = sBuildChannel._platformName;
            if (sBuildChannel._platformName == BuildPipelineUtils.SPlatformType.Android)
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("_androidIcon"), true);
            }
            else if (platformName == BuildPipelineUtils.SPlatformType.IOS)
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("_iosIcon"), true);
            }
        }
    }

    [CreateAssetMenu(fileName = "SBuildData", menuName = "ScriptableObject/BuildPipelineConfig/SBuildChannelData",
        order = 1)]
    public class BuildChannel : SingleScriptableObject<BuildChannel>
    {
        [FoldoutMust("基础信息", true)] [Head("渠道名")] [DefinedValues(nameof(GetChannelNames))]
        public string _channelName;

        [Head("平台名")] [DefinedValues(nameof(GetPlatformNames))]
        public string _platformName;

        [Head("包名")] [DefinedValues(nameof(GetPackageName))]
        public string _packageName;

        [Head("产品名")] [DefinedValues(nameof(GetProductName))]
        public string _productName;

        [Head("公司名")] [DefinedValues(nameof(GetCompanyName))]
        public string _companyName;

        [Head("构建平台")] public BuildPlatformBase _buildPlatform;

        [Head("游戏Icon路径")] [DirectoryField] public string _appIconPath;

        [Head("游戏Splash路径")] [DirectoryField] public string _appSplashPath;

        [FoldoutMust("Android额外设置", true)]
        [ConditionalField(nameof(_platformName), true, "android")]
        [Head("keystor名字")]
        public string _keystoreName;

        [ConditionalField(nameof(_platformName), true, "android")] [Head("keystore密码")]
        public string _keystorePassword;

        [ConditionalField(nameof(_platformName), true, "android")] [Head("keystor别名")]
        public string _keyaliasName;

        [ConditionalField(nameof(_platformName), true, "android")]
        [DefinedValues(nameof(GetAndroidManifest))]
        [Head("AndroidManifest路径")]
        public string _androidManifest;


        [ConditionalField(nameof(_platformName), true, "android")]
        [DefinedValues(nameof(GetAndroidGradle))]
        [Head("AndroidGradle路径")]
        public string _androidGradle;

        [FoldoutMust("Ios额外设置", false)]
        [ConditionalField(nameof(_platformName), true, "ios")]
        [Head("开发证书Profile(UUID)")]
        public string _iOSManualProvisioningProfileID;

        [FoldoutMust("Ios额外设置", false)] [ConditionalField(nameof(_platformName), true, "ios")] [Head("签名类型")]
        public ProvisioningProfileType _iOSManualProvisioningProfileType;

        [FoldoutMust("Ios额外设置", false)]
        [ConditionalField(nameof(_platformName), true, "ios")]
        [Head("推送证书Profile(UUID)")]
        public string _IosNotificationServiceProvision;

        [FoldoutMust("Ios额外设置", false)] [ConditionalField(nameof(_platformName), true, "ios")] [Head("开发TeamID")]
        public string _teamId;

        [SerializeField] public List<SAndroidIconData> _androidIcon =
            new List<SAndroidIconData>();

        [SerializeField] public List<SIosIconData> _iosIcon =
            new List<SIosIconData>();

        private string[] GetChannelNames()
        {
            return new[]
            {
                BuildPipelineUtils.SChannelType.GooglePlay,
                BuildPipelineUtils.SChannelType.AppStore,
                BuildPipelineUtils.SChannelType.Windows,
            };
        }

        private string[] GetPlatformNames()
        {
            return new[]
            {
                BuildPipelineUtils.SPlatformType.Windows,
                BuildPipelineUtils.SPlatformType.MacOSX,
                BuildPipelineUtils.SPlatformType.Android,
                BuildPipelineUtils.SPlatformType.IOS,
            };
        }

        private string[] GetPackageName()
        {
            return new[]
            {
                "com.mfy.global",
            };
        }

        private string[] GetProductName()
        {
            return new[]
            {
                "Clash Guys",
            };
        }

        private string[] GetCompanyName()
        {
            return new[]
            {
                "centurygame",
            };
        }


        private string[] GetAndroidManifest()
        {
            if (BuildPipelineConfig.Instance == null)
            {
                return null;
            }

            string mCopyTopPath = "/../BuildHelper";
            string mCopyAndroidPath = $"{mCopyTopPath}/Android";
            string param01 = BuildPipelineConfig.Instance._release == BuildPipelineUtils.STargetType.Release
                ? "Release"
                : "Dev";

            string param02 = null;
            if (_channelName == BuildPipelineUtils.SChannelType.GooglePlay)
            {
                param02 = "GooglePC";
            }

            string path;
            if (string.IsNullOrEmpty(param02))
            {
                path = $"{mCopyAndroidPath}/manifest/AndroidManifest_{param01}.xml";
            }

            else
            {
                path = $"{mCopyAndroidPath}/manifest/AndroidManifest_{param01}_{param02}.xml";
            }

            return new[]
            {
                path,
            };
        }

        private string[] GetAndroidGradle()
        {
            if (BuildPipelineConfig.Instance == null)
            {
                return null;
            }

            string mCopyTopPath = "/../BuildHelper";
            string mCopyAndroidPath = $"{mCopyTopPath}/Android";
            string copyPath = "";
            // release 
            if (BuildPipelineConfig.Instance._release == BuildPipelineUtils.STargetType.Release)
            {
                copyPath = $"{mCopyAndroidPath}/gradle/mainTemplate_release.gradle";
            }
            else
            {
                Debug.Log($"[Auto] DoCopyGradle dev");
                copyPath = $"{mCopyAndroidPath}/gradle/mainTemplate_dev.gradle";
            }

            return new[]
            {
                copyPath,
            };
        }

        public BuildTargetGroup GetBuildTargetGroup()
        {
            if (_platformName == BuildPipelineUtils.SPlatformType.Android)
                return BuildTargetGroup.Android;
            else if (_platformName == BuildPipelineUtils.SPlatformType.Windows)
                return BuildTargetGroup.Standalone;
            else if (_platformName == BuildPipelineUtils.SPlatformType.MacOSX)
                return BuildTargetGroup.Standalone;
            else if (_platformName == BuildPipelineUtils.SPlatformType.IOS)
                return BuildTargetGroup.iOS;
            return BuildTargetGroup.Android;
        }

        public UnityEditor.BuildTarget GetBuildTarget()
        {
            if (_platformName == BuildPipelineUtils.SPlatformType.Android)
                return UnityEditor.BuildTarget.Android;
            else if (_platformName == BuildPipelineUtils.SPlatformType.Windows)
                return UnityEditor.BuildTarget.StandaloneWindows64;
            else if (_platformName == BuildPipelineUtils.SPlatformType.MacOSX)
                return UnityEditor.BuildTarget.StandaloneOSX;
            else if (_platformName == BuildPipelineUtils.SPlatformType.IOS)
                return UnityEditor.BuildTarget.iOS;
            return UnityEditor.BuildTarget.Android;
        }

        private void Save()
        {
            EditorUtility.SetDirty(this);
            AssetDatabase.SaveAssets();
        }

        [ButtonMethod]
        private void CollectAppIcon()
        {
            if (_platformName == BuildPipelineUtils.SPlatformType.Android)
            {
                CollectAndroidIcon();
            }
            else if (_platformName == BuildPipelineUtils.SPlatformType.IOS)
            {
                CollectIosIcon();
            }
        }


        #region AndroidIcon

        public enum SAndroidPlatformIconKind
        {
            Adaptive = 1,
            Round = 2,
            Legacy = 3,
        }

        private static readonly List<string> IconMipMapList = new List<string>()
        {
            "mipmap-xxxhdpi",
            "mipmap-xxhdpi",
            "mipmap-xhdpi",
            "mipmap-hdpi",
            "mipmap-mdpi",
            "mipmap-ldpi",
        };

        [Serializable]
        public class AppIconMipData
        {
            [HideInInspector] public string _mipMapName;
            [SerializeField] public List<Texture2D> _texture = new List<Texture2D>();
        }

        [Serializable]
        public class SAndroidIconData
        {
            public SAndroidPlatformIconKind _androidIconKind;
            [SerializeField] public List<AppIconMipData> _appIcon;

            public SAndroidIconData(SAndroidPlatformIconKind sAndroidPlatformIconKind)
            {
                _androidIconKind = sAndroidPlatformIconKind;
                _appIcon = new List<AppIconMipData>();
            }
        }

        private void CollectAndroidIcon()
        {
            _iosIcon.Clear();
            _androidIcon.Clear();
            _androidIcon.Add(new SAndroidIconData(SAndroidPlatformIconKind.Adaptive));
            _androidIcon.Add(new SAndroidIconData(SAndroidPlatformIconKind.Round));
            _androidIcon.Add(new SAndroidIconData(SAndroidPlatformIconKind.Legacy));
            for (int index = 0; index < IconMipMapList.Count; index++)
            {
                var mipMapName = IconMipMapList[index];
                //adaptive
                var adaptive = _androidIcon[0];
                var appIconMipData = new AppIconMipData();
                adaptive._appIcon.Add(appIconMipData);
                appIconMipData._mipMapName = mipMapName;

                var texturePath = $"{_appIconPath}/{mipMapName}/ic_launcher_background.png";
                appIconMipData._texture.Add(AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath));
                texturePath = $"{_appIconPath}/{mipMapName}/ic_launcher_foreground.png";
                appIconMipData._texture.Add(AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath));

                //gound
                var ground = _androidIcon[1];
                appIconMipData = new AppIconMipData();
                ground._appIcon.Add(appIconMipData);
                appIconMipData._mipMapName = mipMapName;

                texturePath = $"{_appIconPath}/{mipMapName}/ic_launcher_round.png";
                appIconMipData._texture.Add(AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath));

                //legacy
                var legacy = _androidIcon[2];
                appIconMipData = new AppIconMipData();
                legacy._appIcon.Add(appIconMipData);
                appIconMipData._mipMapName = mipMapName;

                texturePath = $"{_appIconPath}/{mipMapName}/ic_launcher.png";
                appIconMipData._texture.Add(AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath));
            }

            Save();
        }

        #endregion

        #region IosIcon

        [Serializable]
        public class SIosIconData
        {
            public IconKind _iconKind;
            [SerializeField] public List<AppIconMipData> _appIcon;

            public SIosIconData(IconKind iconKind)
            {
                _iconKind = iconKind;
                _appIcon = new List<AppIconMipData>();
            }
        }

        private void CollectIosIcon()
        {
            _androidIcon.Clear();
            _iosIcon.Clear();
            _iosIcon.Add(new SIosIconData(IconKind.Application));
            var buildGroup = GetBuildTargetGroup();
            //Application
            var iconSizes = PlayerSettings.GetIconSizesForTargetGroup(buildGroup, IconKind.Application);
            SIosIconData applicationIcon = this._iosIcon[0];
            var appIconMipData = new AppIconMipData();
            for (var i = 0; i < iconSizes.Length; ++i)
            {
                var texturePath = $"{_appIconPath}/{buildGroup}_{iconSizes[i]}.png";
                appIconMipData._texture.Add(AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath));
            }

            applicationIcon._appIcon.Add(appIconMipData);

            //Store
            _iosIcon.Add(new SIosIconData(IconKind.Store));
            iconSizes = PlayerSettings.GetIconSizesForTargetGroup(buildGroup, IconKind.Store);
            SIosIconData storeIcon = this._iosIcon[1];
            appIconMipData = new AppIconMipData();
            for (var i = 0; i < iconSizes.Length; ++i)
            {
                var texturePath = $"{_appIconPath}/{buildGroup}_{iconSizes[i]}.png";
                appIconMipData._texture.Add(AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath));
            }

            storeIcon._appIcon.Add(appIconMipData);
            Save();
        }

        #endregion


        #region BuildChannel

        private void DoCopyGradle()
        {
            string destPath = Application.dataPath + "/Plugins/Android/mainTemplate.gradle";
            if (File.Exists(destPath))
            {
                File.Delete(destPath);
            }

            FileUtil.CopyFileOrDirectory(Application.dataPath + _androidGradle, destPath);
        }

        private void DoCopyAndroidManifest()
        {
            string androidManifestPath = "/Plugins/Android/AndroidManifest.xml";
            FileUtil.ReplaceFile(Application.dataPath + _androidManifest, Application.dataPath + androidManifestPath);
        }

        private void DoCopyAndroidSplash()
        {
            UnityUtils.CopyDirectory(Path.Combine(Application.dataPath, _appSplashPath),
                Path.Combine(Application.dataPath, "StreamingAssets"));
            AssetDatabase.Refresh();
        }

        private void DoCopyAndroidIcon()
        {
            var buildTargetGroup = GetBuildTargetGroup();
            var adaptiveIcons = PlayerSettings.GetPlatformIcons(buildTargetGroup, AndroidPlatformIconKind.Adaptive);
            var roundIcons = PlayerSettings.GetPlatformIcons(buildTargetGroup, AndroidPlatformIconKind.Round);
            var legacyIcons = PlayerSettings.GetPlatformIcons(buildTargetGroup, AndroidPlatformIconKind.Legacy);
            foreach (var sAndroidIcon in _androidIcon)
            {
                PlatformIcon[] eachIcons = null;
                if (sAndroidIcon._androidIconKind == SAndroidPlatformIconKind.Adaptive)
                {
                    eachIcons = adaptiveIcons;
                }
                else if (sAndroidIcon._androidIconKind == SAndroidPlatformIconKind.Round)
                {
                    eachIcons = roundIcons;
                }
                else if (sAndroidIcon._androidIconKind == SAndroidPlatformIconKind.Legacy)
                {
                    eachIcons = legacyIcons;
                }

                for (int index = 0; index < sAndroidIcon._appIcon.Count; index++)
                {
                    eachIcons[index].SetTextures(sAndroidIcon._appIcon[index]._texture.ToArray());
                }
            }

            PlayerSettings.SetPlatformIcons(buildTargetGroup, AndroidPlatformIconKind.Adaptive, adaptiveIcons);
            PlayerSettings.SetPlatformIcons(buildTargetGroup, AndroidPlatformIconKind.Round, roundIcons);
            PlayerSettings.SetPlatformIcons(buildTargetGroup, AndroidPlatformIconKind.Legacy, legacyIcons);
        }

        private void DoCopyIOSIcon()
        {
            var buildTargetGroup = GetBuildTargetGroup();
            //appIcon
            var iconSizes = PlayerSettings.GetIconSizesForTargetGroup(buildTargetGroup, IconKind.Application);
            foreach (var iosIcon in _iosIcon)
            {
                if (iosIcon._iconKind == IconKind.Application)
                {
                    PlayerSettings.SetIconsForTargetGroup(buildTargetGroup, iosIcon._appIcon[0]._texture.ToArray(),
                        IconKind.Application);
                }
                else if (iosIcon._iconKind == IconKind.Store)
                {
                    PlayerSettings.SetIconsForTargetGroup(buildTargetGroup, iosIcon._appIcon[0]._texture.ToArray(),
                        IconKind.Store);
                }
            }
        }

        private void SetBoot()
        {
        }

        private void CopyProjectProfile()
        {
            if (_platformName == BuildPipelineUtils.SPlatformType.Android)
            {
                //CGSettings.AndroidSplashIsShowEnabled = true;
                DoCopyGradle();
                DoCopyAndroidManifest();
                DoCopyAndroidIcon();
                DoCopyAndroidSplash();
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
            else if (_platformName == BuildPipelineUtils.SPlatformType.IOS)
            {
                DoCopyIOSIcon();
            }
        }

        [ButtonMethod]
        public void SBuildPlatform()
        {
            //构建平台
            $"[BuildPackage] {_platformName} Start_____________________".Log();
            if (_platformName == BuildPipelineUtils.SPlatformType.Android)
            {
                _buildPlatform = new BuildAndroidPlatform();
            }
            else if (_platformName == BuildPipelineUtils.SPlatformType.IOS)
            {
                _buildPlatform = new BuildIOSPlatform();
            }
            else if (_platformName == BuildPipelineUtils.SPlatformType.Windows)
            {
                _buildPlatform = new BuildWindowsPlatform();
            }
         
            $"[BuildPackage] {_platformName} End_____________________".Log();
        }

        [ButtonMethod]
        public void SBuild()
        {
            $"[BuildPackage] {_channelName} Start_____________________".Log();
            //拷贝工程配置文件
            CopyProjectProfile();
            //boot 设置   
            SetBoot();
            $"[BuildPackage] {_channelName} End_____________________".Log();
        }

        #endregion
    }
}